#!/bin/sh
# nosignal-keybinds-gen — parse the NoSignal keymap markdown and emit display-ready
# cheatsheet lines on stdout. The markdown is the SINGLE SOURCE OF TRUTH; the
# on-screen help (nosignal-keybinds) is always derived from it, so the two cannot
# drift. Reads every "| keys | action |" table row except the "Source map"
# section.
#
# Panel format: two columns only — key, action — sized so every
# line fits the fuzzel panel:
#   - no section tag column (visual noise in the popup; the markdown keeps it)
#   - doc-only parentheticals are stripped from actions: provenance notes like
#     "(Omarchy key)", "(was hover-only)" belong in the doc,
#     not the panel. Meaningful ones ("(logout / shutdown / reboot)") stay.
#   - actions are ellipsis-truncated so no line exceeds $NOSIGNAL_KEYS_COLS
#     characters (default 98 — the nosignal-keybinds fuzzel width of 100 minus
#     margin). Keep the two in sync.
#
# Usage: nosignal-keybinds-gen [path-to-markdown]
#   Source resolution order: $1 arg → $NOSIGNAL_KEYMAP_MD → known locations.
set -eu

MD="${1:-${NOSIGNAL_KEYMAP_MD:-}}"
if [ -z "$MD" ]; then
  for cand in "$HOME/Downloads/NoSignal-keybindings.md" \
              "$HOME/.local/share/nosignal/NoSignal-keybindings.md"; do
    [ -f "$cand" ] && { MD="$cand"; break; }
  done
fi
[ -n "${MD:-}" ] && [ -f "$MD" ] || {
  echo "nosignal-keybinds-gen: keymap markdown not found (set \$NOSIGNAL_KEYMAP_MD)" >&2
  exit 1
}

awk -v cols="${NOSIGNAL_KEYS_COLS:-98}" '
function trim(s){ gsub(/\*\*/, "", s); gsub(/^[ \t]+|[ \t]+$/, "", s); return s }

# ---- section headings -------------------------------------------------------
/^## / {
  insrc = (substr($0, 4) ~ /^Source map/)     # not keybinds: skip the section
  next
}
insrc { next }

# ---- table rows -------------------------------------------------------------
/^\|/ {
  if ($0 ~ /^[|: -]+$/) next                   # markdown separator row
  n = split($0, c, "|")                        # c[1] is empty (text before first |)
  keys = c[2]; gsub(/`/, "", keys); keys = trim(keys)
  if (keys == "" || keys == "Keys" || keys == "File") next
  desc = ""
  for (i = 3; i < n; i++) {                     # join any remaining columns
    cell = c[i]; gsub(/`/, "", cell); cell = trim(cell)
    if (cell != "") desc = (desc == "") ? cell : desc " — " cell
  }

  # strip doc-only parentheticals (provenance/changelog), keep the rest
  out = ""; rest = desc
  while (match(rest, /\([^()]*\)/)) {
    pre = substr(rest, 1, RSTART - 1)
    par = substr(rest, RSTART, RLENGTH)
    rest = substr(rest, RSTART + RLENGTH)
    if (par ~ /Omarchy|change [0-9]+|^\(was |moved |NoSignal|dev\/debug/) par = ""
    out = out pre par
  }
  desc = out rest
  gsub(/  +/, " ", desc)                        # collapse gaps left by stripping
  gsub(/[ \t]+$/, "", desc)
  sub(/ — $/, "", desc)

  KEY[++r] = keys; DSC[r] = desc
  if (length(keys) > wk) wk = length(keys)
}

END {
  budget = cols - wk - 2                        # action space after the key column
  for (i = 1; i <= r; i++) {
    d = DSC[i]
    if (length(d) > budget) d = substr(d, 1, budget - 1) "…"
    printf "%-*s  %s\n", wk, KEY[i], d
  }
}
' "$MD"
